﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace auco
{
    class Program
    {
        static Settings set = new Settings();                   //Global Settings
        static sug suggestions = new sug();
        static sug lastSugesstion = null;

        static void Main()
        {
            ConsoleKeyInfo temp;                          //Temp keyboard key
            string text = "";                             //Full text
            string lastWord = "";                         //Just the last word
            sug[] complete = new sug[set.numOfSug];       //The suggestions

            print("", complete);

            while(!set.quit)
            {
                temp = Console.ReadKey(true);
                
                if (temp.Key == ConsoleKey.Backspace && text.Length > 0)
                { text = text.Remove(text.Length - 1); }
                else if (temp.Key == ConsoleKey.RightArrow || 
                         temp.Key == ConsoleKey.LeftArrow  || 
                         temp.Key == ConsoleKey.UpArrow    || 
                         temp.Key == ConsoleKey.DownArrow)
                { }
                else if (temp.Key == ConsoleKey.Tab) {
                    if (text != "")
                    {
                        if (complete[0] == null)
                        {
                            addToChain(lastWord).addUsage();
                        }
                        else
                        {
                            text = text.Remove(text.Length - lastWord.Length);
                            text += complete[0].getSug();
                            lastSugesstion.addUsage();
                            addUsage(lastSugesstion);
                            text += " ";
                        }
                    }
                }
                else if (temp.Key == ConsoleKey.Spacebar)
                {
                    if (complete[0] == null)
                        addToChain(lastWord).addUsage();
                    else addUsage(complete[0]);
                    text += " ";
                }else if (temp.Key == ConsoleKey.Enter)
                {
                    //Do Nothing
                }
                else { text += temp.KeyChar; }

                if (text.Length == 1)
                    if (text[0] == (char)8)
                        text = "";

                //Seperate last word from text
                lastWord = text.Substring(text.LastIndexOf(' ') + 1);

                //Generating suggestions to the last word
                complete = generateSuggestions(lastWord, suggestions);

                print(text, complete);
            }
        }
        static sug[] generateSuggestions(string lastWord, sug suggestions)
        {
            sug[] complete = new sug[set.numOfSug];
            if (lastWord == "") return complete;
            sug current = suggestions;
            int location=0;

            while(location<set.numOfSug&&current!=null){
                if (current.getSug().StartsWith(lastWord))
                {
                    complete[location] = current;
                    location++;
                }
                current = current.getNext();
            }
            lastSugesstion = complete[0];
            return complete;
        }
        static void print(string text, sug[] suggestions)
        {
            string lastWord = text.Substring(text.LastIndexOf(' ') + 1);

            Console.BackgroundColor = set.bgColor;
                Console.Clear();
            Console.ForegroundColor = set.textColor;

                Console.Write(text);
                if (suggestions[0] != null)
                {
                    Console.ForegroundColor = set.suggestionColor;
                    Console.WriteLine(suggestions[0].getSug().Substring(lastWord.Length));
                }
            Console.ForegroundColor = set.suggestionColor;
            for (int i = 1; i < suggestions.Length; i++)
            {
                if(suggestions[i]!=null)
                    Console.WriteLine(suggestions[i].getSug());
            }
            Console.ResetColor();
        }
        static void addUsage(sug chosen)
        {
            sug current = suggestions;
            bool stop = false;

            //Delete from chain
            while (current != null && !stop)
            {
                if (current == chosen)
                {
                    suggestions = current.getNext();
                    stop = true;
                }
                else if (current.getNext() == chosen)
                {
                    current.setNext(chosen.getNext());
                    stop = true;
                }
                else current = current.getNext();
            }

            current = suggestions;
            stop = false;

            //Add to chain in new place
            while (current != null && !stop)
            {
                if (current.getNext() == null)
                {
                    current.setNext(chosen);
                    stop = true;
                }
                else if (current.getPopularity() > chosen.getPopularity() &&
                           current.getNext().getPopularity() < chosen.getPopularity())
                {
                    chosen.setNext(current.getNext());
                    current.setNext(chosen);
                    stop = true;
                }
                else if (current.getPopularity() == chosen.getPopularity())
                {
                    chosen.setNext(current.getNext());
                    current.setNext(chosen);
                    stop = true;
                }
                else if (current.getPopularity() < chosen.getPopularity())
                {   
                    chosen.setNext(current);
                    suggestions = chosen;
                    stop = true;
                }
                else current = current.getNext();
            }
        }
        static sug addToChain(string word)
        {
            word = word.Trim(new char[] {'.', ',', '"', '\'', '!', '(', ')', '/', '\\', ' ', '?'});
            bool stop = false;

            sug current = suggestions;
            while(current.getNext()!=null && !stop){
                if (current.getSug() == word) stop = true;
                current = current.getNext();
            }
            if(!stop)
                current.setNext(new sug(word));

            return current.getNext();
        }
    }
}
